#define _CRT_SECURE_NO_WARNINGS 1

//#include <stdio.h>
//#include <stdlib.h>
//
//void BubbleSort(int arr[], int sz)
//{
//	for (int i = 0; i < sz - 1; i++) {
//		for (int j = 0; j < sz - 1 - i; j++) {
//			if (arr[j] > arr[j + 1]) {
//				int tmp = arr[j];
//				arr[j] = arr[j + 1];
//				arr[j + 1] = tmp;
//			}
//		}
//	}
//}
//
//void PrintArray(int arr[], int sz)
//{
//	for (int i = 0; i < sz; i++) {
//		printf("%d ", arr[i]);
//	}
//	putchar('\n');
//}
//
//void test1()
//{
//	// 想排序一组整型数据
//	int arr[] = { 3,1,5,7,9,2,4,0,8,6 };
//	int sz = sizeof(arr) / sizeof(arr[0]);
//
//	BubbleSort(arr, sz);
//	PrintArray(arr, sz);
//}
//
//int cmp_int(const void* p1, const void* p2)
//{
//	return *(int*)p1 - *(int*)p2;
//}
//
//void test2()
//{
//	int arr[] = { 3,1,5,7,9,2,4,0,8,6 };
//	int sz = sizeof(arr) / sizeof(arr[0]);
//
//	qsort(arr, sz, sizeof(arr[0]), cmp_int);
//	PrintArray(arr, sz);
//}
//
//void Swap(char* buf1, char* buf2, size_t width)
//{
//	// 无法确定什么临时变量，那就每个字节交换
//	for (int i = 0; i < width; i++) {
//		char tmp = *buf1;
//		*buf1 = *buf2;
//		*buf2 = tmp;
//		buf1++;
//		buf2++;
//	}
//}
//
//void BubbleSort2(void* base, size_t sz, size_t width, int (*cmp)(const void* p1, const void* p2))
//{
//	for (int i = 0; i < sz - 1; i++) {
//		for (int j = 0; j < sz - 1 - i; j++) {
//			// if (arr[j] > arr[j + 1])
//			if (cmp((char*)base + j * width, (char*)base + (j + 1) * width) > 0) {
//				/*int tmp = arr[j];
//				arr[j] = arr[j + 1];
//				arr[j + 1] = tmp;*/
//				// 交换
//				Swap((char*)base + j * width, (char*)base + (j + 1) * width, width);
//			}
//		}
//	}
//}
//
//void test3()
//{
//	// 设计和实现BubbleSort2()，这个函数能够排序任意类型的数据
//	int arr[] = { 3,1,5,7,9,2,4,0,8,6 };
//	int sz = sizeof(arr) / sizeof(arr[0]);
//
//	BubbleSort2(arr, sz, sizeof(arr[0]), cmp_int);
//	PrintArray(arr, sz);
//}
//
//struct Stu
//{
//	char name[20];
//	int age;
//};
//
//int cmp_stu_by_name(const void* p1, const void* p2)
//{
//	return (((struct Stu*)p1)->name, ((struct Stu*)p2)->name);
//}
//
//int cmp_stu_by_age(const void* p1, const void* p2)
//{
//	return ((struct Stu*)p1)->age - ((struct Stu*)p2)->age;
//}
//
//void PrintStu(struct Stu s[], int sz)
//{
//	for (int i = 0; i < sz; i++) {
//		printf("%s\n", s[i].name);
//		printf("%d\n", s[i].age);
//	}
//	putchar('\n');
//}
//
//void test4()
//{
//	struct Stu arr[] = { {"ZhangSan", 18},{"LiSi", 35}, {"WangWu", 15} };
//	int sz = sizeof(arr) / sizeof(arr[0]);
//
//	PrintStu(arr, sz);
//	BubbleSort2(arr, sz, sizeof(arr[0]), cmp_stu_by_name);
//	PrintStu(arr, sz);
//}
//
//
//int main()
//{
//	// test1();
//	// test2();
//	// test3();
//	// test4();
//
//	return 0;
//}

//#include <stdio.h>
//#include <string.h>
//
//int main()
//{
	//int a = 10;
	//printf("%zd\n", sizeof(a));
	//printf("%zd\n", sizeof(int));
	//printf("%zd\n", sizeof a); // 可以省略括号
	//printf("%zd\n", sizeof int); // err

	//int arr1[4] = { 0 };
	//char arr2[4] = { 0 };
	//printf("%zd\n", sizeof(arr1)); // 16
	//printf("%zd\n", sizeof(arr2)); // 4

	//char arr[] = "abcdef";
	//printf("%zd\n", strlen(arr));

	//char arr1[3] = { 'a', 'b', 'c' };
	//char arr2[] = "abc";

	//printf("%d\n", strlen(arr1));
	//printf("%d\n", strlen(arr2));

	//printf("%d\n", sizeof(arr1));
	//printf("%d\n", sizeof(arr2));
//	return 0;
//}

//int main()
//{
//	//int a = 10;
//	//printf("%zd\n", sizeof(a));
//	//printf("%zd\n", sizeof(int));
//	//printf("%zd\n", sizeof a);//这里可以省略括号
//	//printf("%zd\n", sizeof int);//err
//
//	int arr1[4] = { 0 };
//	char arr2[4] = { 0 };
//	printf("%zd\n", sizeof(arr1));//16
//	printf("%zd\n", sizeof(int [4]));//16
//
//	printf("%zd\n", sizeof(arr2));//4
//	printf("%zd\n", sizeof(char [4]));//4
//
//	return 0;
//}

//数组名的理解
//数组名一般表示数组首元素的地址
//但是有2个例外：
//1. sizeof(数组名)，数组名表示整个数组，计算的是整个数组的大小，单位是字节
//2. &数组名，数组名表示整个数组，取出的数组的地址
//除此之外，所有遇到的数组名都是数组首元素的地址
//
//
//int main()
//{
//	int a[] = { 1,2,3,4 };//a数组有4个元素，每个元素是int类型的数据
//
//	printf("%zd\n", sizeof(a));//16 - sizeof(数组名)的情况，计算的是整个数组的大小，单位是字节 - 16
//	printf("%zd\n", sizeof(a + 0));//a表示的就是数组首元素的地址,a+0还是首元素的地址 - 4/8
//	//int*
//	printf("%zd\n", sizeof(*a));//a表示的就是数组首元素的地址,*a 就是首元素，大小就是4个字节
//	printf("%zd\n", sizeof(a + 1));//a表示的就是数组首元素的地址，a+1就是第二个元素的地址，这里的计算的是第二个元素的地址的大小-4/8
//
//	printf("%zd\n", sizeof(a[1]));//a[1]是数组的第二个元素，大小是4个字节
//	printf("%zd\n", sizeof(&a));//&a - 取出的是数组的地址，但是数组的地址也是地址，是地址，大小就是4/8个字节
//	//int (*pa)[4] = &a
//	//int(*)[4]
//	printf("%zd\n", sizeof(*&a));//sizeof(a) -16
//	//1. & 和 * 抵消
//	//2.&a 的类型是数组指针，int(*)[4]，*&a就是对数组指针解引用访问一个数组的大小，是16个字节
//
//	printf("%zd\n", sizeof(&a + 1));//&a+1是跳过整个数组后的一个地址，是地址，大小就是4/8个字节
//
//	printf("%zd\n", sizeof(&a[0]));//&a[0]是数组第一个元素的地址，大小就是4/8个字节
//	printf("%zd\n", sizeof(&a[0] + 1));//&a[0] + 1 是第二个元素的地址，大小就是4/8个字节
//	                      //int*
//	return 0;
//}
//

//int main()
//{
//	char arr[] = { 'a','b','c','d','e','f' };//arr数组中有6个元素
//
//	printf("%d\n", sizeof(arr));//计算的是整个数组的大小，6个字节
//	printf("%d\n", sizeof(arr + 0));//arr+0 是数组第一个元素的地址 4/8
//	printf("%d\n", sizeof(*arr));//*arr是首元素，计算的是首元素的大小，就是1个字节
//	printf("%d\n", sizeof(arr[1]));//arr[1]  - 1
//	printf("%d\n", sizeof(&arr));//4/8
//	printf("%d\n", sizeof(&arr + 1));//4/8
//	printf("%d\n", sizeof(&arr[0] + 1));//4/8
//
//	return 0;
//}
//

//int main()
//{
//	char arr[] = { 'a','b','c','d','e','f' };
//	printf("%d\n", strlen(arr));//随机值
//	printf("%d\n", strlen(arr + 0));//随机值
//	//'a'-97
////printf("%d\n", strlen(*arr));//err
////                   //'b'-98
////printf("%d\n", strlen(arr[1]));//err
//	printf("%d\n", strlen(&arr));//随机值
//	printf("%d\n", strlen(&arr + 1));//随机值
//	printf("%d\n", strlen(&arr[0] + 1));//随机值
//
//	return 0;
//}